// ignore_for_file: constant_identifier_names

import 'dart:math';

import 'package:xvideos/hj_model/actress_info.dart';
import 'package:xvideos/hj_model/button_link_model.dart';
import 'package:xvideos/hj_model/message/search_user_obj.dart';
import 'package:xvideos/hj_model/splash/ads_model.dart';
import 'package:xvideos/hj_utils/date_time_util.dart';

import '../config/address.dart';
import '../tools_base/global_store/store.dart';
import 'cartoon_media_info.dart';
import 'home/module_detail_model.dart';

// 帖子类型
const NEWSTYPE_VIDEO = 'SP';
const NEWSTYPE_CVIDEO = 'CSP';
// 帖子类型
const NEWSTYPE_COVER_VIDEO = 'COVER_SP';
// 图片帖子
const NEWSTYPE_IMG = 'COVER';
// 广告
const NEWSTYPE_AD_VIDEO = 'AD_SP';
// 广告
const NEWSTYPE_AD_IMG = 'AD_COVER';

/// 内存缓存模型对象
class LocalVideCache {
  List<VideoModel>? dataArr;
  List<AllSection>? allSection;
  int? page;
  bool? hasNext;

  LocalVideCache({
    this.dataArr,
    this.page,
    this.hasNext,
    this.allSection,
  });
}

class VideoModel {
  static List<VideoModel> toList(List<Map<String, dynamic>> mapList) {
    return mapList.map((e) => VideoModel.fromJson(e)).toList();
  }

  // 短视频业务用到，二级短视频列表数据没有获取权限，需要通过详情接口获取，边播放边刷新数据。
  VideoModel? detailVModel;
  bool isLoadingDetail = false;
  bool? isCollectionVid; //是否是合集视频
  bool? isBuyCollectionVid; //是否购买了该合集
  int? coins; // 折扣价格
  int? originCoins; // 原价
  int? promotionDays;
  int? hot;
  int? commentCount;
  String? cover;
  String? desc;
  String? coverThumb;
  String? createdAt;
  bool? isResourceType;

  String? get createAtFix {
    if (createdAt?.contains("0001-01-01") == true || createdAt?.isNotEmpty != true) {
      return reviewAt;
    }
    return createdAt;
  }

  String? createdAtNotDeal;
  String? reviewAt;
  int? freeTime;
  int? previewStart; //预览时间起始
  String? richText; //图文html
  bool isFreeTimeGroup(int sec) {
    int start = previewStart ?? 0;
    int end = start + (freeTime ?? 0);
    if (sec >= start && sec <= end) {
      return true;
    }
    return false;
  }

  String? id;
  int? likeCount;
  int? collectCount;
  String? content;
  int? uid;
  String? seedLink;
  int? seedSize; //种子大小
  // 种子时长
  String? seedTime;

  // 种子链接下载所需金币
  int? seedCoin;

  int? playCount;
  int? pageViewCount;
  int? payCount;
  int? videoCount;
  int? playTime;
  String? reason; //审核拒绝理由
  ///是否免费观看
  bool? freeArea;
  Publisher? publisher;

//  bool? isCollect;
  int? purchaseCount;

  bool? get isGirl => publisher?.gender == "female";
  double? ratio; //视频宽高比，没返回或者0，强制设置16/9
  String? resolution;
  int? shareCount;
  int? size;
  int? type;
  String? sourceID;
  String? sourceURL;
  String? title;
  String? name; // 动漫番号
  int? totalEpisode; // 动漫集数
  int? updateStatus; //更新状态 0 默认(已完结) 1、更新中 2、已完结
  String? mediaType;
  String? summary;
  String? linkStr; // 富文本
  String? via;
  CommentBean? comment;
  VidStatus? vidStatus;
  int? playStatus = 0; //0：暂停  1：加载   2：播放
  List<String>? seriesCover;
  CartoonMediaInfo? mediaInfo; // 动漫信息；
  String? newsType;
  AdsInfoModel? randomAdsInfo;
  List<AdsInfoModel>? adsInfoArr;
  int? videoType; // 0视频， 1 动漫
  String? subid; // 动漫集数id
  int? subPrice;
  int? currentEpisode;
  String? superId;
  int? dislikeCount;
  int? permission; //动漫权限 0:会员 1:金币购买 2:免费
  List<ActressInfo>? actresses;
  String? vid;
  int playContentStyle = 1; // 1:源视频,2:中文字幕,3:破解版（无码）
  String? chineseLink; // 中文字幕
  String? codelessLink; // 无码链接 马赛克
  /// 广告链接
  String? linkUrl;
  String? localPath; // 本地路径
  String? loadProgress; // 进度
  bool isSelected = false;
  String? previewURL;

  //0 未审核 1通过 2审核失败 3视为免费 5、已下架
  int? status;
  List<TagsBean>? tags;
  bool get isDarkTag {
    for (TagsBean item in (tags ?? [])) {
      if (item.name?.contains("暗网") == true) {
        return true;
      }
    }
    return false;
  }
  String? isLoaderRunning; // 1 正在下载  2 下载完成
  String? token;
  bool? isTopping;

  String? seedLinkUrl;
  int? seedPlayTime;

  String get seedPlayTimeDesc {
    int count = seedPlayTime ?? 0;
    if (count > 0) {
      return DateTimeUtil.getTimeText(seedPlayTime?.toDouble() ?? 0.0);
    }
    return "";
  }

  String get seedLinkDesc {
    String linkDescContent = seedLinkUrl ?? "";
    if (seedLinkUrl?.isNotEmpty == true) {
      var linkArr = seedLinkUrl?.split("[种子链接]:") ?? [];
      if (linkArr.length == 2) {
        linkDescContent = linkArr.first;
      }
      linkArr = seedLinkUrl?.split("[下载链接]:") ?? [];
      if (linkArr.length == 2) {
        linkDescContent = linkArr.first;
      }
    }
    return linkDescContent;
  }

  String get seedRealLink {
    if (seedLinkUrl?.isNotEmpty == true) {
      var linkArr = seedLinkUrl?.split("[种子链接]:") ?? [];
      if (linkArr.length == 2) {
        return linkArr.last;
      }
      linkArr = seedLinkUrl?.split("[下载链接]:") ?? [];
      if (linkArr.length == 2) {
        return linkArr.last;
      }
    }
    return seedLinkUrl ?? "";
  }

  // 用户首页热门推荐
  List<VideoModel> communityHotVideo = [];

  bool get isShortTypeTime {
    return (playTime ?? 300) < 300;
  }

  String get realVideoUrl {
    return "${Address.baseApiPath}/vid/h5/m3u8/$sourceURL?token=${Address.token}&c=${Address.cdnAddress}";
    // return '${Address.baseHost}${Address.API_PREFIX}${Address.VIDEO_SUFFIX}/$sourceURL?Authorization=${Address.token}';
  }

  String get realUncodeUrl {
    return "${Address.baseApiPath}/vid/h5/m3u8/$codelessLink?token=${Address.token}&c=${Address.cdnAddress}";
    // return '${Address.baseHost}${Address.API_PREFIX}${Address.VIDEO_SUFFIX}/$sourceURL?Authorization=${Address.token}';
  }

  String get realChineseUrl {
    return "${Address.baseApiPath}/vid/h5/m3u8/$chineseLink?token=${Address.token}&c=${Address.cdnAddress}";
    // return '${Address.baseHost}${Address.API_PREFIX}${Address.VIDEO_SUFFIX}/$sourceURL?Authorization=${Address.token}';
  }

  String get realPreviewUrl {
    return "${Address.baseApiPath}/vid/h5/m3u8/$previewURL?token=${Address.token}&c=${Address.cdnAddress}";
  }

  String get allTags {
    return tags?.map((e) => e.name).join(' ') ?? '';
  }

  bool get hasLiked {
    if (vidStatus == null) return false;
    return vidStatus?.hasLiked ?? false;
  }

  bool get hasCollected {
    if (vidStatus == null) return false;
    return vidStatus?.hasCollected ?? false;
  }

  double get progress {
    if (loadProgress == null) {
      return 0.0;
    }
    double ret = (double.tryParse(loadProgress ?? "0") ?? 0) / 100;
    return ret;
  }

  bool isRandomAd() {
    return randomAdsInfo != null;
  }

  bool isAdsArr() {
    return adsInfoArr != null;
  }

  List<HotBloggerEntity> hotUpList = [];
  bool isHotUp() {
    return hotUpList.isNotEmpty;
  }

  int videoCoin() {
    if (globalStore.isVIP()) {
      return coins ?? 0;
    }
    return originCoins ?? 0;
  }

  String get seedSizeDesc {
    return "${seedSize}Mb";
  }

  bool isCoinVideo() {
    if ((coins ?? 0) > 0 || (originCoins ?? 0) > 0) {
      return true;
    }
    return false;
  }

  int? get realCoins {
    if (globalStore.isVIP() == true) {
      return coins;
    }
    return originCoins;
  }

  //评论类型，传参数类型
  String get commentType => 'video';

  bool? chosen; // 置精
  ButtonLinkModel? button;

  VideoModel({this.id});

  VideoModel.fromJson(Map<dynamic, dynamic>? map) {
    map ??= {};
    button = ButtonLinkModel.fromJson(map["button"]);
    richText = map['richText'];
    previewStart = map['previewStart'];
    isCollectionVid = map['isCollectionVid'];
    isBuyCollectionVid = map['isBuyCollectionVid'];
    if (map['hot'] != null) {
      if (map['hot'] is int) {
        hot = map['hot'];
      } else if (map['hot'] is double) {
        hot = (map['hot'] as double).toInt();
      } else {
        hot = int.tryParse(map['hot'].toString());
      }
    }
    if (map['permission'] is int) {
      permission = map['permission'];
    }
    chineseLink = map['chineseLink'];
    codelessLink = map["codelessLink"];
    chosen = map['chosen'];
    uid = map["uid"];
    isTopping = map['isTopping'];
    seedCoin = map["seedCoin"];
    seedPlayTime = map['seedPlayTime'];
    seedLinkUrl = map['seedLinkUrl'];

    seedLink = map['seedLink'];
    seedTime = map["seedTime"];
    seedSize = map["seedSize"];
    dislikeCount = map["dislikeCount"];
    superId = map["superId"];
    subid = map["subid"];
    content = map["content"];
    coins = map['coins'];
    purchaseCount = map['purchaseCount'];
    originCoins = map['originCoins'];
    promotionDays = map['promotionDays'];
    commentCount = map['commentCount'];
    cover = map['cover'];
    desc = map['desc'];
    coverThumb = map['coverThumb'];
    createdAt = map['createdAt'];
    createdAtNotDeal = map['createdAt'];
    reviewAt = map['reviewAt'];
    freeTime = map['freeTime'];
    id = map['id'];
    likeCount = map['likeCount'];
    collectCount = map['collectCount'];
    playCount = map['playCount'];
    pageViewCount = map['pageViewCount'];
    payCount = map['payCount'] ?? 0;
    videoCount = map['videoCount'] ?? 0;
    playTime = map['playTime'];
    publisher = Publisher.fromMap(map['publisher']);
    ratio = double.tryParse((map['ratio'] ?? '').toString());
    if (ratio == null || ratio == 0) ratio = 16 / 9;
    resolution = map['resolution'];
    shareCount = map['shareCount'];
    size = map['size'];
    type = map['type'];
    sourceID = map['sourceID'];
    isResourceType = map["isResourceType"];
    sourceURL = map['sourceURL'];
    previewURL = map['previewURL'];
    status = map['status'];
    freeArea = map['freeArea'];
    name = map['name'];
    tags = (map['tags'] as List?)?.map((o) => o is String ? TagsBean() : TagsBean.fromMap(o)).toList();
    title = map['title'];
    via = map['via'];
    comment = map.containsKey("comment") ? CommentBean.fromMap(map['comment']) : null;
    vidStatus = VidStatus.fromMap(map['vidStatus']);
    if (map['seriesCover'] is List) {
      List<String> covers = (map['seriesCover'] as List).map((e) => e.toString()).toList();
      seriesCover = covers;
    }
    newsType = map['newsType'];
    reason = map['reason'];
    linkUrl = map['linkUrl'];
    linkStr = map['linkStr'];
    totalEpisode = map['totalEpisode'];
    updateStatus = map['updateStatus'];
    mediaType = map['mediaType'];
    vid = map['vid'];
    videoType = map['videoType'];
    if (map['actresses'] is List) {
      actresses = [...(map['actresses'] as List).map((o) => ActressInfo.fromJson(o))];
    }
  }

  Map<String, dynamic> toJson() => {
        'richText': richText,
        'previewStart': previewStart,
        'videoType': videoType,
        "coins": coins,
        "originCoins": originCoins,
        "promotionDays": promotionDays,
        "commentCount": commentCount,
        "cover": cover,
        "desc": desc,
        "coverThumb": coverThumb,
        "createdAt": createdAt,
        "createdAtNotDeal": createdAtNotDeal,
        "reviewAt": reviewAt,
        "freeTime": freeTime,
        "id": id,
        'permission': permission,
        "likeCount": likeCount,
        "playCount": playCount,
        "pageViewCount": pageViewCount,
        "playTime": playTime,
        "publisher": publisher,
        "ratio": ratio,
        "resolution": resolution,
        "shareCount": shareCount,
        "size": size,
        "type": type,
        "sourceID": sourceID,
        "sourceURL": sourceURL,
        "previewURL": previewURL,
        "status": status,
        "mediaInfo": mediaInfo?.toJson(),
        "tags": tags,
        "title": title,
        "via": via,
        "vidStatus": vidStatus,
        "comment": comment,
        "playStatus": playStatus,
        "freeArea": freeArea,
        "seriesCover": seriesCover,
        "newsType": newsType,
        'reason': reason,
        'linkUrl': linkUrl,
        'linkStr': linkStr,
        'totalEpisode': totalEpisode,
        'updateStatus': updateStatus,
        'mediaType': mediaType,
        'vid': vid,
      };

  //集数状态描述
  String get episodeNumberStatus {
    return mediaInfo?.episodeNumberStatus ?? '';
  }

  String getUpdateString() {
    String unit = '集';
    if (mediaType == 'image') {
      unit = '话';
    }
    if (updateStatus == 1) {
      return '更新$totalEpisode$unit';
    } else if (updateStatus == 2 || updateStatus == 0) {
      return '已完结';
    } else {
      return '已完结';
    }
  }
}

//图集和黄游
extension LockType on VideoModel {
  //图集解锁样式 0-不需要解锁 1-金币解锁 2-会员解锁
  int get picLockType {
    //1.免费
    if (freeArea == true) return 0;
    //2.自己发布
    if (globalStore.isMe(publisher?.uid)) return 0;
    //3.金币解锁
    if ((originCoins ?? 0) > 0) {
      //是否购买
      if (vidStatus?.hasPaid == true) return 0;
      //是否免费
      if (coins == 0) return 0;
      //是否vip等级>=2
      if (globalStore.isVIPTwoLevel()) return 0;
      return 1;
    } else {
      //vip解锁
      if (globalStore.isRechargeVIP()) return 0;
      return 2;
    }
  }

  //黄游解锁样式 0-不需要解锁 1-金币解锁
  int get gameLockType {
    //1.免费
    if (freeArea == true) return 0;
    //2.自己发布
    if (globalStore.isMe(publisher?.uid)) return 0;
    //3.金币解锁
    if ((originCoins ?? 0) > 0) {
      //是否购买
      if (vidStatus?.hasPaid == true) return 0;
      //是否免费
      if (coins == 0) return 0;
      //是否vip等级>=2
      if (globalStore.isVIPTwoLevel()) return 0;
      return 1;
    }
    return 0;
  }
}

extension Post on VideoModel {
  bool isVideo() {
    return newsType == 'SP' || newsType == 'MOVIE'|| newsType == 'SHORT'|| newsType == 'COVER';
  }

  bool isSeedPost() {
    return newsType == 'ADULT_GAME' || (seedLink?.isNotEmpty ?? false) || newsType == 'SEED_LINK';
  }

  /// 图集权限
  bool coversPermission() {
    if (isVideo() || isSeedPost()) return true;
    final isme = globalStore.isMe(publisher?.uid ?? 0);
    if (isme) return true;
    if (permission == 2) return true;
    final vipLevel = globalStore.meInfo?.vipLevel ?? 0;
    if (permission == 0) {
      return vipLevel > 0;
    }
    return vidStatus?.hasPaid ?? false;
  }

  /// 视频权限
  bool videoPermission() {
    /**
     * 帖子权限
     * 金币帖子 是否购买过
     * 会员帖子 会员等级是否大于1
     */
    final isme = globalStore.isMe(publisher?.uid ?? 0);
    if (isme) return true;
    if (permission == 2) return true;
    final vipLevel = globalStore.meInfo?.vipLevel ?? 0;
    if (permission == 0) {
      return vipLevel > 0;
    }
    return vidStatus?.hasPaid ?? false;
  }

  String getAvailable() {
    final cover_ = cover ?? '';
    if (cover_.isNotEmpty) return cover_;
    if (seriesCover?.isNotEmpty ?? false) return seriesCover!.first;
    return '';
  }

  int showPicturesMaxLength() {
    final length = seriesCover?.length ?? 0;
    // if (isVideonNew) return length;
    // if (coversPermission()) return length;
    // // 检查图片多少张
    // // 大于三张显示三张（还要加一张显示解锁信息，所以应该是4张）， 其余显示一张
    // if (length == 0) return 0;
    // if (length >= 3) return 3;
    return length; // 跟测试沟通后，本项目没有楼凤贴，少于等于3张就全部显示
  }

  int getTotalCovers() => (seriesCover ?? []).length + ((cover ?? '').isEmpty ? 0 : 1);

  List<String> getItemCovers() {
    final covers = <String>[]..addAll(seriesCover ?? []);
    final cover_ = cover ?? '';

    if (isVideo()) {
      if (covers.isEmpty) {
        if (cover_.isEmpty) return [];
        return [cover_];
      } else {
        if (cover_.isEmpty) {
          final length = covers.length;
          final end = min(3, length);
          return covers.sublist(0, end);
        }
        covers.remove(cover_);
        final length = covers.length;
        final end = min(2, length);

        return covers.sublist(0, end)..add(cover_);
      }
    }
    final length = covers.length;
    final end = min(3, length);
    return covers.sublist(0, end);
  }

/*

*/
}

class VidStatus {
  bool? hasCollected;
  bool? hasLiked;
  bool? hasPaid;
  int? todayPlayCnt;
  int? todayRank;
  bool? hasDisliked;
  bool? hasPaidSeed;
  bool? hasGraded;
  bool? hasAddBookshelf;
  bool? hasRead;

  static VidStatus fromMap(Map<String, dynamic>? map) {
    map ??= {};
    VidStatus info = VidStatus();
    info.hasCollected = map['hasCollected'];
    info.hasLiked = map['hasLiked'];
    info.hasPaid = map['hasPaid'];
    info.todayPlayCnt = map['todayPlayCnt'];
    info.todayRank = map['todayRank'];
    info.hasDisliked = map['hasDisliked'];
    info.hasPaidSeed = map['hasPaidSeed'];
    info.hasGraded = map['hasGraded'];
    info.hasAddBookshelf = map['hasAddBookshelf'];
    info.hasRead = map['hasRead'];
    return info;
  }

  Map toJson() => {
        "hasDisliked": hasDisliked,
        "hasCollected": hasCollected,
        "hasLiked": hasLiked,
        "hasPaid": hasPaid,
        "todayPlayCnt": todayPlayCnt,
        "todayRank": todayRank,
        "hasPaidSeed": hasPaidSeed,
        "hasGraded": hasGraded,
        "hasAddBookshelf": hasAddBookshelf,
        "hasRead": hasRead,
      };
}

class TagsBean {
  String? coverImg;
  String? description;
  bool? hasCollected;
  String? id;
  String? name;
  int? playCount;
  int? type;
  String? hotMark;
  String? tagName;
  int? videoCount;
  int? collCount;
  bool isSelected = false;
  int? vidCount;
  int? followCount;
  String? newsType;

  TagsBean({this.id, this.name});

  //兼容name和tagname，后台返回不一致
  String? get mergeName {
    if (tagName != null && tagName?.isNotEmpty == true) {
      return tagName;
    } else {
      return name;
    }
  }

  TagsBean.fromMap(Map<String, dynamic>? map) {
    map ??= {};
    vidCount = map['vidCount'];
    followCount = map['followCount'];
    hotMark = map['hotMark'];
    tagName = map['tagName'];
    videoCount = map['videoCount'];
    coverImg = map['coverImg'];
    description = map['description'];
    hasCollected = map['hasCollected'];
    id = map['id'];
    name = map['name'];
    type = map['type'];
    playCount = map['playCount'];
    collCount = map['collCount'];
  }

  Map<String, dynamic> toJson() => {
        "coverImg": coverImg,
        "description": description,
        "hasCollected": hasCollected,
        "id": id,
        "name": name,
        "playCount": playCount,
        "tagName": tagName,
      };
}

class Publisher {
  int? age;
  String? gender;
  bool? hasFollowed;
  String? name;

  String? get realName => name?.replaceAll(" \t\n", "") ?? "";
  String? portrait;
  int? uid;
  int? vipLevel; //月卡 季卡 年卡
  bool? isVip;
  String? createdAt;

  bool get realVip {
    return (vipLevel ?? 0) > 0;
  }

  String get vipIcon {
    if (vipLevel == 1 || vipLevel == 2) return 'user_vip_small.png';
    return 'super_vip.png';
  }

  bool? superUser; //大v
  int? activeValue; //活跃值
  bool? officialCert; //官方认证
  int? rechargeLevel; //vip等级 vip1-vip8
  int? fans;
  int? merchantUser; //认证商户
  List<int> awards = [];
  String? upTag;
  int? totalWorks;
  String? vipName;

  Publisher();

  Publisher.fromMap(Map<String, dynamic>? map) {
    map ??= {};
    if (map['awards'] is List) {
      awards = [...(map['awards'] as List).map((o) => o)];
    }
    totalWorks = map['totalWorks'];
    upTag = map['upTag'];
    merchantUser = map['merchantUser'];
    age = map['age'];
    gender = map['gender'];
    hasFollowed = map['hasFollowed'];
    name = map['name'];
    portrait = map['portrait'];
    uid = map['uid'];
    vipLevel = map['vipLevel'];
    isVip = map['isVip'];
    if (map['superUser'] is bool) {
      superUser = map['superUser'];
    } else if (map['superUser'] is int) {
      superUser = map['superUser'] >= 1;
    }
    activeValue = map['activeValue'];
    officialCert = map['officialCert'];
    rechargeLevel = map['rechargeLevel'];
    fans = map['fans'];
    vipName = map['vipName'];
  }

  Map toJson() => {
        "age": age,
        "gender": gender,
        "hasFollowed": hasFollowed,
        "name": name,
        "portrait": portrait,
        "uid": uid,
        "vipLevel": vipLevel,
        "isVip": isVip,
        "superUser": superUser,
        "activeValue": activeValue,
        "officialCert": officialCert,
        "rechargeLevel": rechargeLevel,
      };
}

class CommentBean {
  int? uid;
  String? name;
  String? portrait;
  String? cid;
  String? content;
  int? likeCount;
  bool? isAuthor;
  String? createdAt;

  CommentBean.fromMap(Map<String, dynamic>? map) {
    map ??= {};
    uid = map['uid'];
    name = map['name'];
    portrait = map['portrait'];
    cid = map['cid'];
    content = map['content'];
    likeCount = map['likeCount'];
    isAuthor = map['isAuthor'];
    createdAt = map['createdAt'];
  }

  Map toJson() => {
        "uid": uid,
        "name": name,
        "portrait": portrait,
        "cid": cid,
        "content": content,
        "likeCount": likeCount,
        "isAuthor": isAuthor,
        "createdAt": createdAt,
      };
}
